﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DAO;
using DTO;
using System.Data;
using System.Globalization;
using System.Drawing;

namespace BUS
{
    public class SpriteBUS
    {
        public static int ToInt(string str)
        {
            int outInt = 0;
            int.TryParse(str, out outInt);
            return outInt;
        }
        public static int ToXInt(string str)
        {
            int outInt = 0;
            int.TryParse(str, NumberStyles.AllowHexSpecifier,
                CultureInfo.InvariantCulture.NumberFormat, out outInt);
            return outInt;
        }

        public static SpriteDTO Load(string filename)
        {
            return SpriteDAO.Load(filename);
        }

        public static SpriteDTO ImportBSprite(string filename)
        {
            return SpriteDAO.ImportBSprite(filename);
        }

        public static void Save(SpriteDTO sprite, string filename)
        {
            SpriteDAO.Save(sprite, filename);
        }

        public static DataTable GetDataModule(SpriteDTO sprite)
        {
            DataTable dTable = SpriteDAO.GetTableModule();
            dTable.Rows.Clear();
            // populate the DataTable using DataRow object
            DataRow row = null;
            for (int i = 0; i < sprite.Modules.Count; i++)
            {
                Module module = sprite.Modules[i];
                row = dTable.NewRow();
                row["No"] = i + 1;
                //row["Status"] = module.Status.ToString();
                row["Id"] = module.Id.ToString("X");
                row["X"] = module.X;
                row["Y"] = module.Y;
                row["W"] = module.W;
                row["H"] = module.H;
                row["Desc"] = module.Desc;
                dTable.Rows.Add(row);
            }

            return dTable;
        }
        //public static void SetEditModule(int index)
        //{
        //    DataTable dTable = SpriteDAO.GetTableModule();
        //    dTable.Rows[index]["Status"] = "Edited";
        //}
        public static void NewRowModule(SpriteDTO sprite)
        {
            Module module = new Module();
            if (sprite.Modules.Count == 0)
            {
                module.Id = 0x1000;
            }
            else
            {
                int maxId = sprite.Modules[0].Id;
                for (int i = 1; i < sprite.Modules.Count; i++)
                {
                    if (maxId < sprite.Modules[i].Id)
                    {
                        maxId = sprite.Modules[i].Id;
                    }
                }
                module.Id = maxId + 1;
            }
            sprite.Modules.Add(module);
            GetDataModule(sprite);
        }
        public static void NewRowModule(SpriteDTO sprite, Rectangle boundRect)
        {
            Module module = new Module();
            if (sprite.Modules.Count == 0)
            {
                module.Id = 0x1000;
            }
            else
            {
                int maxId = sprite.Modules[0].Id;
                for (int i = 1; i < sprite.Modules.Count; i++)
                {
                    if (maxId < sprite.Modules[i].Id)
                    {
                        maxId = sprite.Modules[i].Id;
                    }
                }
                module.Id = maxId + 1;
            }
            module.X = boundRect.X;
            module.Y = boundRect.Y;
            module.W = boundRect.Width;
            module.H = boundRect.Height;

            sprite.Modules.Add(module);
            GetDataModule(sprite);
        }
        public static bool CloneRowModule(SpriteDTO sprite, int index)
        {
            if (index < 0 || index >= sprite.Modules.Count)
                return false;

            Module module = new Module();

            int maxId = sprite.Modules[0].Id;
            for (int i = 1; i < sprite.Modules.Count; i++)
            {
                if (maxId < sprite.Modules[i].Id)
                {
                    maxId = sprite.Modules[i].Id;
                }
            }
            module.Id = maxId + 1;
            module.X = sprite.Modules[index].X;
            module.Y = sprite.Modules[index].Y;
            module.W = sprite.Modules[index].W;
            module.H = sprite.Modules[index].H;
            module.Desc = sprite.Modules[index].Desc;
            module.Status = sprite.Modules[index].Status;

            sprite.Modules.Add(module);
            GetDataModule(sprite);
            return true;
        }
        public static void SaveRowModule(SpriteDTO sprite, int index)
        {
            DataTable dTable = SpriteDAO.GetTableModule();
            if (index < 0 || index > dTable.Rows.Count)
            {
                return;
            }

            DataRow row = dTable.Rows[index];
            sprite.Modules[index].X = (int)row["X"];
            sprite.Modules[index].Y = (int)row["Y"];
            sprite.Modules[index].W = (int)row["W"];
            sprite.Modules[index].H = (int)row["H"];
            sprite.Modules[index].Desc = row["Desc"] != DBNull.Value ? (string)row["Desc"] : "";
            sprite.Modules[index].Status = EditStatus.Saved;
            //row["Status"] = "Saved";


            //GetDataModule(sprite);
        }
        public static void SaveAllModule(SpriteDTO sprite)
        {
            DataTable dTable = SpriteDAO.GetTableModule();

            for (int i = 0; i < dTable.Rows.Count; i++)
            {

                //if ((string)dTable.Rows[i]["Status"] == "Edited")
                {
                    DataRow row = dTable.Rows[i];
                    sprite.Modules[i].X = (int)row["X"];
                    sprite.Modules[i].Y = (int)row["Y"];
                    sprite.Modules[i].W = (int)row["W"];
                    sprite.Modules[i].H = (int)row["H"];
                    sprite.Modules[i].Desc = (string)row["Desc"];
                    sprite.Modules[i].Status = EditStatus.Saved;
                    //row["Status"] = "Saved";
                }
            }
            //GetDataModule(sprite);
        }
        public static void DelRowModule(SpriteDTO sprite, int index)
        {
            DataTable dTable = SpriteDAO.GetTableModule();
            if (index < 0 || index > dTable.Rows.Count)
            {
                return;
            }

            sprite.Modules.RemoveAt(index);
            dTable.Rows.RemoveAt(index);
            //GetDataModule(sprite);
        }
        public static bool ModuleRowUp(SpriteDTO sprite, int index)
        {
            if (index <= 0 || index >= sprite.Modules.Count)
                return false;
            Module tmpMod = sprite.Modules[index];
            sprite.Modules[index] = sprite.Modules[index - 1];
            sprite.Modules[index - 1] = tmpMod;

            GetDataModule(sprite);
            return true;
        }
        public static bool ModuleRowDown(SpriteDTO sprite, int index)
        {
            if (index < 0 || index >= sprite.Modules.Count - 1)
                return false;
            Module tmpMod = sprite.Modules[index];
            sprite.Modules[index] = sprite.Modules[index + 1];
            sprite.Modules[index + 1] = tmpMod;

            GetDataModule(sprite);
            return true;
        }
        public static Rectangle GetBoundRect(SpriteDTO sprite, int X, int Y)
        {
            Rectangle boundRect = new Rectangle(X, Y, 1, 1);
            if (sprite.ImageInfo.Count == 0)
                return boundRect;
            Color[,] buffData = sprite.ImageInfo[0].BuffData;
            int W = sprite.ImageInfo[0].Image.Width;
            int H = sprite.ImageInfo[0].Image.Height;
            if (X < 0 ||
                X >= W ||
                Y < 0 ||
                Y >= H)
                return boundRect;
            Color trans = Color.FromArgb(sprite.ImageInfo[0].Transp);
            if (Equal(buffData[X, Y], trans))
                return boundRect;

            bool flagCon = true;
            while (flagCon)
            {
                X = boundRect.X;
                Y = boundRect.Y;
                flagCon = false;
                //
                int k = X - 1;
                bool flag = true;
                while (flag && k >= 0)
                {
                    flag = false;
                    for (int j = boundRect.Y; j < boundRect.Y + boundRect.Height; j++)
                    {
                        if (buffData[k, j].A != 0 && !Equal(buffData[k, j], trans))
                        {
                            flag = true;
                            flagCon = true;
                        }
                    }
                    if (flag == false)
                        break;
                    k--;
                }
                boundRect.X = k + 1;

                //
                k = X + boundRect.Width;
                flag = true;
                while (flag && k < W)
                {
                    flag = false;
                    for (int j = boundRect.Y; j < boundRect.Y + boundRect.Height; j++)
                    {
                        if (buffData[k, j].A != 0 && !Equal(buffData[k, j], trans))
                        {
                            flag = true;
                            flagCon = true;
                        }
                    }
                    if (flag == false)
                        break;
                    k++;
                }
                boundRect.Width = k - boundRect.X;

                //
                k = Y - 1;
                flag = true;
                while (flag && k >= 0)
                {
                    flag = false;
                    for (int i = boundRect.X; i < boundRect.X + boundRect.Width; i++)
                    {
                        if (buffData[i, k].A != 0 && !Equal(buffData[i, k], trans))
                        {
                            flag = true;
                            flagCon = true;
                        }
                    }
                    if (flag == false)
                        break;
                    k--;
                }
                boundRect.Y = k + 1;

                //
                k = Y + boundRect.Height;
                flag = true;
                while (flag && k < H)
                {
                    flag = false;
                    for (int i = boundRect.X; i < boundRect.X + boundRect.Width; i++)
                    {
                        if (buffData[i, k].A != 0 && !Equal(buffData[i, k], trans))
                        {
                            flag = true;
                            flagCon = true;
                        }
                    }
                    if (flag == false)
                        break;
                    k++;
                }
                boundRect.Height = k - boundRect.Y;
            }
            return boundRect;
        }
        public static bool Equal(Color c1, Color c2)
        {
            return c1.R == c2.R &&
                c1.G == c2.G &&
                c1.B == c2.B;
        }

        public static DataTable GetDataFrame(SpriteDTO sprite)
        {
            DataTable dTable = SpriteDAO.GetTableFrames();
            dTable.Rows.Clear();
            // populate the DataTable using DataRow object
            DataRow row = null;
            for (int i = 0; i < sprite.Frames.Count; i++)
            {
                Frame frame = sprite.Frames[i];
                row = dTable.NewRow();
                row["No"] = i + 1;
                //row["Status"] = frame.Status.ToString();
                row["Id"] = frame.Id.ToString("X");
                row["FModules"] = frame.FModules.Count;
                row["Desc"] = frame.Desc;
                dTable.Rows.Add(row);
            }

            return dTable;
        }
        //public static void SetEditFrame(int index)
        //{
        //    DataTable dTable = SpriteDAO.GetTableFrames();
        //    dTable.Rows[index]["Status"] = "Edited";
        //}
        public static void NewRowFrame(SpriteDTO sprite)
        {
            Frame frame = new Frame();
            if (sprite.Frames.Count == 0)
            {
                frame.Id = 0x2000;
            }
            else
            {
                int maxId = sprite.Frames[0].Id;
                for (int i = 1; i < sprite.Frames.Count; i++)
                {
                    if (maxId < sprite.Frames[i].Id)
                    {
                        maxId = sprite.Frames[i].Id;
                    }
                }
                frame.Id = maxId + 1;
            }
            sprite.Frames.Add(frame);
            GetDataFrame(sprite);
        }
        public static bool CloneRowFrame(SpriteDTO sprite, int index)
        {
            if (index < 0 || index >= sprite.Frames.Count)
                return false;

            Frame frame = new Frame(sprite.Frames[index]);

            int maxId = sprite.Frames[0].Id;
            for (int i = 1; i < sprite.Frames.Count; i++)
            {
                if (maxId < sprite.Frames[i].Id)
                {
                    maxId = sprite.Frames[i].Id;
                }
            }
            frame.Id = maxId + 1;

            sprite.Frames.Add(frame);
            GetDataFrame(sprite);
            return true;

        }
        public static void SaveRowFrame(SpriteDTO sprite, int index)
        {
            DataTable dTable = SpriteDAO.GetTableFrames();
            if (index < 0 || index > dTable.Rows.Count)
            {
                return;
            }

            //if ((string)dTable.Rows[index]["Status"] == "Edited")
            {
                DataRow row = dTable.Rows[index];
                sprite.Frames[index].Desc = (string)row["Desc"];
                sprite.Frames[index].Status = EditStatus.Saved;
                //row["Status"] = "Saved";
            }

            //GetDataModule(sprite);
        }
        public static void SaveAllFrame(SpriteDTO sprite)
        {
            DataTable dTable = SpriteDAO.GetTableFrames();

            for (int i = 0; i < dTable.Rows.Count; i++)
            {

                //if ((string)dTable.Rows[i]["Status"] == "Edited")
                {
                    DataRow row = dTable.Rows[i];
                    sprite.Frames[i].Desc = (string)row["Desc"];
                    sprite.Frames[i].Status = EditStatus.Saved;
                    //row["Status"] = "Saved";
                }
            }
            //GetDataModule(sprite);
        }
        public static void DelRowFrame(SpriteDTO sprite, int index)
        {
            DataTable dTable = SpriteDAO.GetTableFrames();
            if (index < 0 || index > dTable.Rows.Count)
            {
                return;
            }

            sprite.Frames.RemoveAt(index);
            dTable.Rows.RemoveAt(index);

            SpriteDAO.GetTableFModules().Rows.Clear();
            //GetDataModule(sprite);
        }
        public static bool FrameRowUp(SpriteDTO sprite, int index)
        {
            if (index <= 0 || index >= sprite.Modules.Count)
                return false;
            Frame tmpFrame = sprite.Frames[index];
            sprite.Frames[index] = sprite.Frames[index - 1];
            sprite.Frames[index - 1] = tmpFrame;

            GetDataFrame(sprite);
            return true;
        }
        public static bool FrameRowDown(SpriteDTO sprite, int index)
        {
            if (index < 0 || index >= sprite.Modules.Count - 1)
                return false;
            Frame tmpFrame = sprite.Frames[index];
            sprite.Frames[index] = sprite.Frames[index + 1];
            sprite.Frames[index + 1] = tmpFrame;

            GetDataFrame(sprite);
            return true;
        }

        public static DataTable GetDataFModule(SpriteDTO sprite, int no)
        {
            DataTable dTable = SpriteDAO.GetTableFModules();
            dTable.Rows.Clear();
            if (no < 0 || no >= sprite.Frames.Count)
                return dTable;
            // populate the DataTable using DataRow object
            DataRow row = null;
            for (int i = 0; i < sprite.Frames[no].FModules.Count; i++)
            {
                FModule fmodule = sprite.Frames[no].FModules[i];
                row = dTable.NewRow();
                row["No"] = i + 1;
                //row["Status"] = fmodule.Status.ToString();
                row["Mid"] = fmodule.Mid.ToString("x"); ;
                row["Ox"] = fmodule.Ox;
                row["Oy"] = fmodule.Oy;
                row["Flag"] = fmodule.Flag.ToString("x") + GenFlipString(fmodule.Flag);
                dTable.Rows.Add(row);
            }

            return dTable;
        }
        //public static void SetEditFModule(int index)
        //{
        //    DataTable dTable = SpriteDAO.GetTableFModules();
        //    dTable.Rows[index]["Status"] = "Edited";
        //}
        public static bool NewRowFModule(SpriteDTO sprite, int FrameIndex)
        {
            if (FrameIndex < 0 || FrameIndex >= sprite.Frames.Count)
                return false;
            FModule fmodule = new FModule();

            sprite.Frames[FrameIndex].FModules.Add(fmodule);
            GetDataFModule(sprite, FrameIndex);

            DataTable dTable = SpriteDAO.GetTableFrames();
            dTable.Rows[FrameIndex]["FModules"] = sprite.Frames[FrameIndex].FModules.Count;
            //GetDataFrame(sprite);
            return true;
        }
        public static bool NewRowFModule(SpriteDTO sprite, int FrameIndex, int mid)
        {
            if (FrameIndex < 0 || FrameIndex >= sprite.Frames.Count)
                return false;
            FModule fmodule = new FModule();
            fmodule.Mid = mid;

            sprite.Frames[FrameIndex].FModules.Add(fmodule);
            GetDataFModule(sprite, FrameIndex);
            DataTable dTable = SpriteDAO.GetTableFrames();
            dTable.Rows[FrameIndex]["FModules"] = sprite.Frames[FrameIndex].FModules.Count;
            return true;
        }
        public static bool CloneRowFModule(SpriteDTO sprite, int FrameIndex, int FModuleIndex)
        {
            if (FModuleIndex < 0 || FModuleIndex >= sprite.Frames[FrameIndex].FModules.Count)
                return false;

            FModule fmodule = new FModule(sprite.Frames[FrameIndex].FModules[FModuleIndex]);

            sprite.Frames[FrameIndex].FModules.Add(fmodule);
            GetDataFModule(sprite, FrameIndex);
            DataTable dTable = SpriteDAO.GetTableFrames();
            dTable.Rows[FrameIndex]["FModules"] = sprite.Frames[FrameIndex].FModules.Count;
            return true;
        }
        public static void SaveRowFModule(SpriteDTO sprite, int FrameIndex, int FModuleIndex)
        {
            DataTable dTable = SpriteDAO.GetTableFModules();
            if (FModuleIndex < 0 || FModuleIndex > dTable.Rows.Count)
            {
                return;
            }

            //if ((string)dTable.Rows[FModuleIndex]["Status"] == "Edited")
            {
                DataRow row = dTable.Rows[FModuleIndex];
                sprite.Frames[FrameIndex].FModules[FModuleIndex].Mid = ToXInt((string)row["Mid"]);
                sprite.Frames[FrameIndex].FModules[FModuleIndex].Ox = (int)row["Ox"];
                sprite.Frames[FrameIndex].FModules[FModuleIndex].Oy = (int)row["Oy"];
                //sprite.Frames[FrameIndex].FModules[FModuleIndex].Flag = (int)row["Flag"];
                sprite.Frames[FrameIndex].FModules[FModuleIndex].Status = EditStatus.Saved;
                //row["Status"] = "Saved";
            }

            //GetDataModule(sprite);
        }

        public static void FlipFModule(SpriteDTO sprite, int FrameIndex, int FModuleIndex, int flipType)
        {
            if (FModuleIndex < 0 || FModuleIndex > sprite.Frames[FrameIndex].FModules.Count)
            {
                return;
            }

            int flag = sprite.Frames[FrameIndex].FModules[FModuleIndex].Flag;
            if ((flag & (flipType)) == 0)
            {
                flag |= (flipType);
            }
            else
            {
                flag &= ~(flipType);
            }
            sprite.Frames[FrameIndex].FModules[FModuleIndex].Flag = flag;

            DataTable dTable = SpriteDAO.GetTableFModules();


            //if ((string)dTable.Rows[FModuleIndex]["Status"] == "Edited")
            {
                DataRow row = dTable.Rows[FModuleIndex];
                row["Flag"] = flag.ToString("x") + GenFlipString(flag);
                sprite.Frames[FrameIndex].FModules[FModuleIndex].Status = EditStatus.Saved;
                //row["Status"] = "Saved";
            }

            //GetDataModule(sprite);
        }

        public static void RotateCWFModule(SpriteDTO sprite, int FrameIndex, int FModuleIndex)
        {
            if (FModuleIndex < 0 || FModuleIndex > sprite.Frames[FrameIndex].FModules.Count)
            {
                return;
            }

            int flag = sprite.Frames[FrameIndex].FModules[FModuleIndex].Flag;

            if ((flag & SpriteDTO.ROTATE_180) != 0)
            {
                if ((flag & SpriteDTO.ROTATE_90) != 0)
                {
                    flag &= ~(SpriteDTO.ROTATE_270);
                }
                else
                {
                    flag |= (SpriteDTO.ROTATE_90);
                }
            }
            else
            {
                if ((flag & SpriteDTO.ROTATE_90) != 0)
                {
                    flag &= ~(SpriteDTO.ROTATE_90);
                    flag |= (SpriteDTO.ROTATE_180);
                }
                else
                {
                    flag |= (SpriteDTO.ROTATE_90);
                }
            }

            sprite.Frames[FrameIndex].FModules[FModuleIndex].Flag = flag;

            DataTable dTable = SpriteDAO.GetTableFModules();


            //if ((string)dTable.Rows[FModuleIndex]["Status"] == "Edited")
            {
                DataRow row = dTable.Rows[FModuleIndex];
                row["Flag"] = flag.ToString("x") + GenFlipString(flag);
                sprite.Frames[FrameIndex].FModules[FModuleIndex].Status = EditStatus.Saved;
                //row["Status"] = "Saved";
            }
        }

        public static void RotateCCWFModule(SpriteDTO sprite, int FrameIndex, int FModuleIndex)
        {
            if (FModuleIndex < 0 || FModuleIndex > sprite.Frames[FrameIndex].FModules.Count)
            {
                return;
            }

            int flag = sprite.Frames[FrameIndex].FModules[FModuleIndex].Flag;
            if ((flag & (SpriteDTO.ROTATE_90)) != 0)
                flag &= ~(SpriteDTO.ROTATE_90);
            else if ((flag & (SpriteDTO.ROTATE_180)) != 0)
            {
                flag &= ~(SpriteDTO.ROTATE_180);
                flag |= (SpriteDTO.ROTATE_90);
            }
            else if ((flag & (SpriteDTO.ROTATE_270)) != 0)
            {
                flag &= ~(SpriteDTO.ROTATE_90);
            }
            else
                flag |= (SpriteDTO.ROTATE_270);

            sprite.Frames[FrameIndex].FModules[FModuleIndex].Flag = flag;

            DataTable dTable = SpriteDAO.GetTableFModules();


            //if ((string)dTable.Rows[FModuleIndex]["Status"] == "Edited")
            {
                DataRow row = dTable.Rows[FModuleIndex];
                row["Flag"] = flag.ToString("x") + GenFlipString(flag);
                sprite.Frames[FrameIndex].FModules[FModuleIndex].Status = EditStatus.Saved;
                //row["Status"] = "Saved";
            }
        }

        public static void AlignTop(SpriteDTO sprite, int FrameIndex, int FModuleIndex)
        {
            sprite.Frames[FrameIndex].FModules[FModuleIndex].Oy = -sprite.GetModule(sprite.Frames[FrameIndex].FModules[FModuleIndex].Mid).H;
            //sprite.Frames[FrameIndex].FModules[FModuleIndex].Ox -= 8;
            DataTable dTable = SpriteDAO.GetTableFModules();

            //if ((string)dTable.Rows[FModuleIndex]["Status"] == "Edited")
            {
                DataRow row = dTable.Rows[FModuleIndex];
                //row["Ox"] = sprite.Frames[FrameIndex].FModules[FModuleIndex].Ox;
                row["Oy"] = sprite.Frames[FrameIndex].FModules[FModuleIndex].Oy;
                sprite.Frames[FrameIndex].FModules[FModuleIndex].Status = EditStatus.Saved;
                //row["Status"] = "Saved";
            }
        }

        public static string GenFlipString(int flag)
        {
            if (flag == 0)
            {
                return " None";
            }
            string outstr = " ";
            if ((flag & SpriteDTO.FLIP_X) != 0)
            {
                outstr += " FLIP_X";
            }

            if ((flag & SpriteDTO.FLIP_Y) != 0)
            {
                outstr += " FLIP_Y";
            }

            if ((flag & SpriteDTO.ROTATE_180) != 0)
            {
                if ((flag & SpriteDTO.ROTATE_90) != 0)
                {
                    outstr += " ROT_270";
                }
                else
                {
                    outstr += " ROT_180";
                }
            }
            else
            {
                if ((flag & SpriteDTO.ROTATE_90) != 0)
                {
                    outstr += " ROT_90";
                }                
            }


            return outstr;
        }

        public static void SaveAllFModule(SpriteDTO sprite, int FrameIndex)
        {
            DataTable dTable = SpriteDAO.GetTableFModules();

            for (int i = 0; i < dTable.Rows.Count; i++)
            {

                //if ((string)dTable.Rows[i]["Status"] == "Edited")
                {
                    DataRow row = dTable.Rows[i];
                    sprite.Frames[FrameIndex].FModules[i].Mid = ToXInt((string)row["Mid"]);
                    sprite.Frames[FrameIndex].FModules[i].Ox = (int)row["Ox"];
                    sprite.Frames[FrameIndex].FModules[i].Oy = (int)row["Oy"];
                    //sprite.Frames[FrameIndex].FModules[i].Flag = (int)row["Flag"];
                    sprite.Frames[FrameIndex].FModules[i].Status = EditStatus.Saved;
                    //row["Status"] = "Saved";
                }
            }
            //GetDataModule(sprite);
        }
        public static void DelRowFModule(SpriteDTO sprite, int FrameIndex, int index)
        {
            DataTable dTable = SpriteDAO.GetTableFModules();
            if (index < 0 || index > dTable.Rows.Count)
            {
                return;
            }

            sprite.Frames[FrameIndex].FModules.RemoveAt(index);
            dTable.Rows.RemoveAt(index);

            dTable = SpriteDAO.GetTableFrames();
            dTable.Rows[FrameIndex]["FModules"] = sprite.Frames[FrameIndex].FModules.Count;
        }
        public static bool FModuleRowUp(SpriteDTO sprite, int FrameIndex, int FModuleIndex)
        {
            if (FrameIndex < 0 || FrameIndex >= sprite.Frames.Count)
                return false;
            if (FModuleIndex <= 0 || FModuleIndex >= sprite.Frames[FrameIndex].FModules.Count)
                return false;


            FModule tmpAFrame = sprite.Frames[FrameIndex].FModules[FModuleIndex];
            sprite.Frames[FrameIndex].FModules[FModuleIndex] = sprite.Frames[FrameIndex].FModules[FModuleIndex - 1];
            sprite.Frames[FrameIndex].FModules[FModuleIndex - 1] = tmpAFrame;

            GetDataFModule(sprite, FrameIndex);
            return true;
        }
        public static bool FModuleRowDown(SpriteDTO sprite, int FrameIndex, int FModuleIndex)
        {
            if (FrameIndex < 0 || FrameIndex >= sprite.Frames.Count)
                return false;
            if (FModuleIndex < 0 || FModuleIndex >= sprite.Frames[FrameIndex].FModules.Count - 1)
                return false;


            FModule tmpAFrame = sprite.Frames[FrameIndex].FModules[FModuleIndex];
            sprite.Frames[FrameIndex].FModules[FModuleIndex] = sprite.Frames[FrameIndex].FModules[FModuleIndex + 1];
            sprite.Frames[FrameIndex].FModules[FModuleIndex + 1] = tmpAFrame;

            GetDataFModule(sprite, FrameIndex);
            return true;
        }

        public static bool TestPointInFModule( FModule fmodule, int x, int y)
        {
            int rot = 0;
            if ((fmodule.Flag & SpriteDTO.ROTATE_180) != 0)
                if ((fmodule.Flag & SpriteDTO.ROTATE_90) != 0)
                    rot = 270;
                else
                    rot = 180;
            else
                if ((fmodule.Flag & SpriteDTO.ROTATE_90) != 0)
                    rot = 90;
            Rectangle rect = new Rectangle(fmodule.Ox,
                fmodule.Oy,
                fmodule.Module.W,
                fmodule.Module.H);

            if (rot == 90)
            {
                rect.X -= fmodule.Module.H;
                rect.Width = fmodule.Module.H;
                rect.Height = fmodule.Module.W;
            }
            else if (rot == 180)
            {
                rect.X -= fmodule.Module.W;
                rect.Y -= fmodule.Module.H;
            }
            else if (rot == 270)
            {
                rect.Y -= fmodule.Module.W;
                rect.Width = fmodule.Module.H;
                rect.Height = fmodule.Module.W;
            }


            if (0 <= x - rect.X && rect.Width >= x - rect.X &&
                0 <= y - rect.Y && rect.Height >= y - rect.Y)
            {
                return true;
            }

            return false;
        }
        public static int FindFModuleContainPoint(SpriteDTO sprite, int rowIndexFrame, int x, int y, int last)
        {
            if (rowIndexFrame < 0 || rowIndexFrame >= sprite.Frames.Count)
                return -1;
            if (last != -1)
            {
                FModule fmodule = sprite.Frames[rowIndexFrame].FModules[last];
                fmodule.Module = sprite.GetModule(fmodule.Mid);
                if (TestPointInFModule(fmodule, x, y))
                    return last;
            }

            for (int i = 0; i < sprite.Frames[rowIndexFrame].FModules.Count; i++)
            {

                FModule fmodule = sprite.Frames[rowIndexFrame].FModules[i];
                fmodule.Module = sprite.GetModule(fmodule.Mid);
                if (TestPointInFModule(fmodule, x, y))
                    return i;
                
                //int rot = 0;
                //if ((fmodule.Flag & SpriteDTO.ROTATE_180) != 0)
                //    if ((fmodule.Flag & SpriteDTO.ROTATE_90) != 0)
                //        rot = 270;
                //    else
                //        rot = 180;
                //else
                //    if ((fmodule.Flag & SpriteDTO.ROTATE_90) != 0)
                //        rot = 90;
                //Rectangle rect = new Rectangle(fmodule.Ox,
                //    fmodule.Oy,
                //    fmodule.Module.W,
                //    fmodule.Module.H);

                //if (rot == 90)
                //{
                //    rect.X -= fmodule.Module.H;
                //    rect.Width = fmodule.Module.H;
                //    rect.Height = fmodule.Module.W;
                //}
                //else if (rot == 180)
                //{
                //    rect.X -= fmodule.Module.W;
                //    rect.Y -= fmodule.Module.H;
                //}
                //else if (rot == 270)
                //{
                //    rect.Y -= fmodule.Module.W;
                //    rect.Width = fmodule.Module.H;
                //    rect.Height = fmodule.Module.W;
                //}
                

                //fmodule.Module = sprite.GetModule(fmodule.Mid);
                //if (0 <= x - rect.X && rect.Width >= x - rect.X &&
                //    0 <= y - rect.Y && rect.Height >= y - rect.Y)
                //{
                //    return i;
                //}
            }
            return -1;
        }
        public static int FindModuleContainPoint(SpriteDTO sprite, int x, int y)
        {
            for (int i = 0; i < sprite.Modules.Count; i++)
            {
                Module mod = sprite.Modules[i];
                if (mod.X <= x && mod.X + mod.W >= x &&
                    mod.Y <= y && mod.Y + mod.H >= y)
                {
                    return i;
                }
            }
            return -1;
        }

        public static DataTable GetDataAnimation(SpriteDTO sprite)
        {
            DataTable dTable = SpriteDAO.GetTableAnimations();
            dTable.Rows.Clear();
            // populate the DataTable using DataRow object
            DataRow row = null;
            for (int i = 0; i < sprite.Animations.Count; i++)
            {
                Animation animation = sprite.Animations[i];
                row = dTable.NewRow();
                row["No"] = i + 1;
                //row["Status"] = animation.Status.ToString();
                row["Id"] = animation.Id.ToString("X");
                row["AFrames"] = animation.AFrames.Count;
                row["Desc"] = animation.Desc;
                dTable.Rows.Add(row);
            }

            return dTable;
        }
        //public static void SetEditAnimation(int index)
        //{
        //    DataTable dTable = SpriteDAO.GetTableAnimations();
        //    dTable.Rows[index]["Status"] = "Edited";
        //}
        public static void NewRowAnimation(SpriteDTO sprite)
        {
            Animation animation = new Animation();
            if (sprite.Animations.Count == 0)
            {
                animation.Id = 0x3000;
            }
            else
            {
                int maxId = sprite.Animations[0].Id;
                for (int i = 1; i < sprite.Animations.Count; i++)
                {
                    if (maxId < sprite.Animations[i].Id)
                    {
                        maxId = sprite.Animations[i].Id;
                    }
                }
                animation.Id = maxId + 1;
            }
            sprite.Animations.Add(animation);
            GetDataAnimation(sprite);
        }
        public static bool CloneRowAnimation(SpriteDTO sprite, int index)
        {
            if (index < 0 || index >= sprite.Frames.Count)
                return false;

            Animation animation = new Animation(sprite.Animations[index]);

            int maxId = sprite.Animations[0].Id;
            for (int i = 1; i < sprite.Animations.Count; i++)
            {
                if (maxId < sprite.Animations[i].Id)
                {
                    maxId = sprite.Animations[i].Id;
                }
            }
            animation.Id = maxId + 1;

            sprite.Animations.Add(animation);
            GetDataAnimation(sprite);
            return true;
        }
        public static void SaveRowAnimation(SpriteDTO sprite, int index)
        {
            DataTable dTable = SpriteDAO.GetTableAnimations();
            if (index < 0 || index > dTable.Rows.Count)
            {
                return;
            }

            //if ((string)dTable.Rows[index]["Status"] == "Edited")
            {
                DataRow row = dTable.Rows[index];
                sprite.Animations[index].Desc = (string)row["Desc"];
                sprite.Animations[index].Status = EditStatus.Saved;
                //row["Status"] = "Saved";
            }

            //GetDataModule(sprite);
        }
        public static void SaveAllAnimation(SpriteDTO sprite)
        {
            DataTable dTable = SpriteDAO.GetTableAnimations();

            for (int i = 0; i < dTable.Rows.Count; i++)
            {

                //if ((string)dTable.Rows[i]["Status"] == "Edited")
                {
                    DataRow row = dTable.Rows[i];
                    sprite.Animations[i].Desc = (string)row["Desc"];
                    sprite.Animations[i].Status = EditStatus.Saved;
                    //row["Status"] = "Saved";
                }
            }
            //GetDataModule(sprite);
        }
        public static void DelRowAnimation(SpriteDTO sprite, int index)
        {
            DataTable dTable = SpriteDAO.GetTableAnimations();
            if (index < 0 || index > dTable.Rows.Count)
            {
                return;
            }

            sprite.Animations.RemoveAt(index);
            dTable.Rows.RemoveAt(index);

            SpriteDAO.GetTableAFrames().Rows.Clear();
            //GetDataModule(sprite);
        }
        public static bool AnimationRowUp(SpriteDTO sprite, int index)
        {
            if (index <= 0 || index >= sprite.Animations.Count)
                return false;
            Animation tmpAnimation = sprite.Animations[index];
            sprite.Animations[index] = sprite.Animations[index - 1];
            sprite.Animations[index - 1] = tmpAnimation;

            GetDataAnimation(sprite);
            return true;
        }
        public static bool AnimationRowDown(SpriteDTO sprite, int index)
        {
            if (index < 0 || index >= sprite.Animations.Count - 1)
                return false;
            Animation tmpAnimation = sprite.Animations[index];
            sprite.Animations[index] = sprite.Animations[index + 1];
            sprite.Animations[index + 1] = tmpAnimation;

            GetDataAnimation(sprite);
            return true;
        }

        public static DataTable GetDataAFrame(SpriteDTO sprite, int no)
        {
            DataTable dTable = SpriteDAO.GetTableAFrames();
            dTable.Rows.Clear();
            if (no < 0 || no >= sprite.Animations.Count)
                return dTable;
            // populate the DataTable using DataRow object
            DataRow row = null;
            for (int i = 0; i < sprite.Animations[no].AFrames.Count; i++)
            {
                AFrame aframe = sprite.Animations[no].AFrames[i];
                row = dTable.NewRow();
                row["No"] = i + 1;
                //row["Status"] = aframe.Status.ToString();
                row["Fid"] = aframe.Fid.ToString("x");
                row["Time"] = aframe.Time;
                row["Ox"] = aframe.Ox;
                row["Oy"] = aframe.Oy;
                row["Flag"] = aframe.Flag.ToString("x") + GenFlipString(aframe.Flag);
                dTable.Rows.Add(row);
            }

            return dTable;
        }
        //public static void SetEditAFrame(int index)
        //{
        //    DataTable dTable = SpriteDAO.GetTableAFrames();
        //    dTable.Rows[index]["Status"] = "Edited";
        //}
        public static bool NewRowAFrame(SpriteDTO sprite, int AnimationIndex)
        {
            if (AnimationIndex < 0 || AnimationIndex >= sprite.Animations.Count)
                return false;
            AFrame aframe = new AFrame();

            sprite.Animations[AnimationIndex].AFrames.Add(aframe);
            GetDataAFrame(sprite, AnimationIndex);

            DataTable dTable = SpriteDAO.GetTableAnimations();
            dTable.Rows[AnimationIndex]["AFrames"] = sprite.Animations[AnimationIndex].AFrames.Count;
            //GetDataAnimation(sprite);
            return true;
        }
        public static bool NewRowAFrame(SpriteDTO sprite, int AnimationIndex, int fid)
        {
            if (AnimationIndex < 0 || AnimationIndex >= sprite.Animations.Count)
                return false;
            AFrame aframe = new AFrame();
            aframe.Fid = fid;

            sprite.Animations[AnimationIndex].AFrames.Add(aframe);
            GetDataAFrame(sprite, AnimationIndex);

            DataTable dTable = SpriteDAO.GetTableAnimations();
            dTable.Rows[AnimationIndex]["AFrames"] = sprite.Animations[AnimationIndex].AFrames.Count;
            return true;
        }
        public static bool CloneRowAFrame(SpriteDTO sprite, int AnimationIndex, int AFrameIndex)
        {
            if (AFrameIndex < 0 || AFrameIndex >= sprite.Animations[AnimationIndex].AFrames.Count)
                return false;

            AFrame aframe = new AFrame(sprite.Animations[AnimationIndex].AFrames[AFrameIndex]);

            sprite.Animations[AnimationIndex].AFrames.Add(aframe);
            GetDataAFrame(sprite, AnimationIndex);
            DataTable dTable = SpriteDAO.GetTableAnimations();
            dTable.Rows[AnimationIndex]["AFrames"] = sprite.Animations[AnimationIndex].AFrames.Count;
            return true;
        }
        public static void SaveRowAFrame(SpriteDTO sprite, int AnimationIndex, int AFrameIndex)
        {
            DataTable dTable = SpriteDAO.GetTableAFrames();
            if (AFrameIndex < 0 || AFrameIndex > dTable.Rows.Count || AnimationIndex < 0)
            {
                return;
            }

            //if ((string)dTable.Rows[AFrameIndex]["Status"] == "Edited")
            {
                DataRow row = dTable.Rows[AFrameIndex];
                sprite.Animations[AnimationIndex].AFrames[AFrameIndex].Fid = ToXInt((string)row["Fid"]);
                sprite.Animations[AnimationIndex].AFrames[AFrameIndex].Time = (int)row["Time"];
                sprite.Animations[AnimationIndex].AFrames[AFrameIndex].Ox = (int)row["Ox"];
                sprite.Animations[AnimationIndex].AFrames[AFrameIndex].Oy = (int)row["Oy"];
                //sprite.Animations[AnimationIndex].AFrames[AFrameIndex].Flag = (int)row["Flag"];
                sprite.Animations[AnimationIndex].AFrames[AFrameIndex].Status = EditStatus.Saved;
                //row["Status"] = "Saved";
            }

            //GetDataModule(sprite);
        }

        public static void FlipAFrame(SpriteDTO sprite, int AnimationIndex, int AFrameIndex, int flipType)
        {
            DataTable dTable = SpriteDAO.GetTableAFrames();
            if (AFrameIndex < 0 || AFrameIndex > dTable.Rows.Count)
            {
                return;
            }

            int flag = sprite.Animations[AnimationIndex].AFrames[AFrameIndex].Flag;
            if ((flag & (flipType)) == 0)
            {
                flag |= (flipType);
            }
            else
            {
                flag &= ~(flipType);
            }
            sprite.Animations[AnimationIndex].AFrames[AFrameIndex].Flag = flag;
            //if ((string)dTable.Rows[AFrameIndex]["Status"] == "Edited")
            {
                DataRow row = dTable.Rows[AFrameIndex];
                row["Flag"] = flag.ToString("x") + GenFlipString(flag);
                sprite.Animations[AnimationIndex].AFrames[AFrameIndex].Status = EditStatus.Saved;
                //row["Status"] = "Saved";
            }

            //GetDataModule(sprite);
        }

        public static void SaveAllAFrame(SpriteDTO sprite, int AnimationIndex)
        {
            DataTable dTable = SpriteDAO.GetTableAFrames();

            for (int i = 0; i < dTable.Rows.Count; i++)
            {

                //if ((string)dTable.Rows[i]["Status"] == "Edited")
                {
                    DataRow row = dTable.Rows[i];
                    sprite.Animations[AnimationIndex].AFrames[i].Fid = ToXInt((string)row["Fid"]);
                    sprite.Animations[AnimationIndex].AFrames[i].Time = (int)row["Time"];
                    sprite.Animations[AnimationIndex].AFrames[i].Ox = (int)row["Ox"];
                    sprite.Animations[AnimationIndex].AFrames[i].Oy = (int)row["Oy"];
                    //sprite.Animations[AnimationIndex].AFrames[i].Flag = (int)row["Flag"];
                    sprite.Animations[AnimationIndex].AFrames[i].Status = EditStatus.Saved;
                    //row["Status"] = "Saved";
                }
            }
            //GetDataModule(sprite);
        }
        public static void DelRowAFrame(SpriteDTO sprite, int AnimationIndex, int AFrameIndex)
        {
            DataTable dTable = SpriteDAO.GetTableAFrames();
            if (AFrameIndex < 0 || AFrameIndex > dTable.Rows.Count)
            {
                return;
            }

            sprite.Animations[AnimationIndex].AFrames.RemoveAt(AFrameIndex);
            dTable.Rows.RemoveAt(AFrameIndex);

            dTable = SpriteDAO.GetTableAnimations();
            dTable.Rows[AnimationIndex]["AFrames"] = sprite.Animations[AnimationIndex].AFrames.Count;
        }
        public static bool AFrameRowUp(SpriteDTO sprite, int AnimationIndex, int AFrameIndex)
        {
            if (AnimationIndex < 0 || AnimationIndex >= sprite.Animations.Count)
                return false;
            if (AFrameIndex <= 0 || AFrameIndex >= sprite.Animations[AnimationIndex].AFrames.Count)
                return false;

            AFrame tmpAFrame = sprite.Animations[AnimationIndex].AFrames[AFrameIndex];
            sprite.Animations[AnimationIndex].AFrames[AFrameIndex] = sprite.Animations[AnimationIndex].AFrames[AFrameIndex - 1];
            sprite.Animations[AnimationIndex].AFrames[AFrameIndex - 1] = tmpAFrame;

            GetDataAFrame(sprite, AnimationIndex);
            return true;
        }
        public static bool AFrameRowDown(SpriteDTO sprite, int AnimationIndex, int AFrameIndex)
        {
            if (AnimationIndex < 0 || AnimationIndex >= sprite.Animations.Count)
                return false;
            if (AFrameIndex < 0 || AFrameIndex >= sprite.Animations[AnimationIndex].AFrames.Count - 1)
                return false;

            AFrame tmpAFrame = sprite.Animations[AnimationIndex].AFrames[AFrameIndex];
            sprite.Animations[AnimationIndex].AFrames[AFrameIndex] = sprite.Animations[AnimationIndex].AFrames[AFrameIndex + 1];
            sprite.Animations[AnimationIndex].AFrames[AFrameIndex + 1] = tmpAFrame;

            GetDataAFrame(sprite, AnimationIndex);
            return true;
        }




    }
}
